#include<iostream>
#include<unistd.h>
#include<cstring>
#include<cstdlib>
#include<cerrno>
#include<semaphore.h>
#include<vector>

using namespace std;

const int n = 5;

template<class T>
class RRQueue
{
public:
  RRQueue(int num = n)
    :_capacity(num)
    ,_data(num)//如果没有在这里开辟num个数的空间，后面[]使用会出段错误
  {
    sem_init(&_data_sem,0,0);//数据信号量的初始值为0
    sem_init(&_space_sem,0,num);//空间信号量的初始值位循环队列的大小
    _c_step = _p_step;
  }

  void P(sem_t& s)
  {
    sem_wait(&s);
  }

  void V(sem_t& s)
  {
    sem_post(&s);
  }

  void push(const T& key)
  {
    P(_space_sem);//要生产数据，申请空间信号量
    _data[_p_step++] = key;
    _p_step %= _capacity;
    V(_data_sem);//生产数据成功，增加数据信号量
  }

  void pop(T& key)
  {
    P(_data_sem);//要消费数据，申请数据信号量
    key = _data[_c_step++];
    _c_step %= _capacity;
    V(_space_sem);//消费数据成功，增加空间信号量
  }

  ~RRQueue()
  {
    sem_destroy(&_data_sem);
    sem_destroy(&_space_sem);
  }
private:
  vector<T> _data;//循环队列
  int _capacity;//容量
  int _c_step;//消费者的位置
  int _p_step;//生产者的位置
  sem_t _data_sem;//数据信号量
  sem_t _space_sem;//空间信号量
};
